package com.zjny.handler;

import com.zjny.enums.ResultEnum;
import com.zjny.pojo.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.Objects;

/**
 * packageName com.zjny.handler
 * 全局异常拦截器
 *
 * @author cui haida
 * @version JDK 8
 * 2025/6/18
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 处理方法参数不合法异常。
     * 当客户端提交的请求参数不满足验证条件时，Spring MVC 会抛出 MethodArgumentNotValidException 异常。
     * 该异常处理器专门捕获此类异常，并将参数验证错误信息转换为统一的响应结果返回给客户端。
     *
     * @param e MethodArgumentNotValidException 异常实例，包含具体的验证错误信息。
     * @return 统一格式的响应结果，其中包含错误代码和错误信息。
     */
    // MethodArgumentNotValidException 的 处理
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseResult<String> exceptionHandler(MethodArgumentNotValidException e) {
        // 初始化错误信息字符串 builder
        StringBuilder error = new StringBuilder();
        // 获取验证结果对象，用于获取具体的错误信息
        BindingResult bindingResult = e.getBindingResult();

        // 检查是否有字段验证错误
        if (bindingResult.hasErrors()) {
            // 遍历所有验证错误，将错误信息追加到 error builder 中
            for (ObjectError allError : bindingResult.getAllErrors()) {
                error.append(allError.getDefaultMessage()).append(";");
            }
            // 返回包含所有验证错误信息的响应结果
            return ResponseResult.fail(ResultEnum.VALIDATE_FAILED, error.toString());
        }

        // 如果没有字段验证错误，获取并返回第一个非字段验证错误信息
        String failMessage = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
        return ResponseResult.fail(ResultEnum.VALIDATE_FAILED, failMessage);
    }
}